﻿using Grow.Module;
using Grow.Module.Service;
using Grow.Scheduler.CreateScheduler;
using Grow.Scheduler.Hangfire.Redis.CreateScheduler;
using Grow.Utils.Exceptions;
using Hangfire;
using Hangfire.Redis;
using Microsoft.Extensions.DependencyInjection;

namespace Grow.Scheduler.Hangfire.Redis
{
    public abstract class SchedulerRedisModuleBase : ModuleBase, ITaskSchedulerModule
    {
        public override ModuleLevel Level => ModuleLevel.Framework;
        public override void AddDependModule(IDependModuleBuilder dependModuleBuilder)
        {
        }
        public override void AddService(IServiceContainer serviceContainer)
        {
            CreateSchedulerBuilder createSchedulerBuilder = new(serviceContainer);
            CreateScheduler(createSchedulerBuilder);
            serviceContainer.BuilderManager.SetBuilder<ICreateSchedulerBuilder>(createSchedulerBuilder);

            _ = serviceContainer.ServiceCollection.AddSingleton<GrowJobActivator>();
            _ = serviceContainer.ServiceCollection.AddTransient<IScheduler, Scheduler>();
        }


        public override void UseService(IServiceContext serviceContext)
        {

            GrowJobActivator growJobActivator = serviceContext.GetRequiredService<GrowJobActivator>();
            SchedulerOptions schedulerOptions = serviceContext.GetOptions<SchedulerOptions>();
            if (string.IsNullOrEmpty(schedulerOptions.ConnectionString))
            {
                throw new GrowFrameworkException($"{nameof(schedulerOptions)}：ConnectionString 为空");
            }
            _ = GlobalConfiguration.Configuration
                       .UseActivator(growJobActivator)
                       .UseRedisStorage(schedulerOptions.ConnectionString, new RedisStorageOptions()
                       {
                           //活动服务器超时时间
                           InvisibilityTimeout = TimeSpan.FromMinutes(60),
                           Db = 0
                       });

            _ = new BackgroundJobServer(new BackgroundJobServerOptions
            {
                SchedulePollingInterval = TimeSpan.FromSeconds(schedulerOptions.UpdateSeconds),
                WorkerCount = Environment.ProcessorCount * schedulerOptions.WorkerCount
            });
        }

        public abstract void CreateScheduler(ICreateSchedulerBuilder createSchedulerBuilder);

    }
}
